package com.system.comm.utils;

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 发送邮件<br>
 * 示例：<br>
 * 参考main方法
 * @author yuejing
 * @date 2016年4月30日 下午7:23:52
 * @version V1.0.0
 */
public class FrameMailUtil {

	private static final Logger LOGGER = LoggerFactory.getLogger(FrameMailUtil.class);

	private MimeMessage mimeMsg;
	private Session session;
	private Properties props;
	private String username;
	private String password;
	private Multipart multiPart;
	private Boolean isSend;
	//附件地址集合
	private List<String> attachFileNames;

	/**
	 * 构造函数
	 * @param smtp		smtp
	 * @param from		发送邮箱
	 * @param username	用户名
	 * @param password	密码
	 */
	public FrameMailUtil(String smtp, String from, String username, String password) {
		this(smtp, from, username, password, true);
	}
	/**
	 * 构造函数
	 * @param smtp		smtp
	 * @param from		发送邮箱
	 * @param username	用户名
	 * @param password	密码
	 * @param isSend	是否打开发送
	 */
	public FrameMailUtil(String smtp, String from, String username, String password, Boolean isSend) {
		this.username = username;
		this.password = password;
		this.isSend = isSend;
		props = System.getProperties();
		props.put("mail.smtp.host", smtp);
		props.put("mail.smtp.auth", "true");
		try {
			session = Session.getDefaultInstance(props, null);
		} catch (Exception e) {
			LOGGER.error("获取邮件会话错误！" + e);
			return;
		}
		try {
			mimeMsg = new MimeMessage(session);
		} catch (Exception e) {
			LOGGER.error("创建MIME邮件对象失败！" + e);
			return;
		}
		try {
			//发信人
			mimeMsg.setFrom(new InternetAddress(from));
		} catch (Exception e) {
			LOGGER.error("发送邮件异常: " + e.getMessage(), e);
			return;
		}
	}

	/**
	 * 定义邮件主题
	 * @param mailSubject
	 * @return
	 */
	public boolean setSubject(String mailSubject) {
		try {
			mimeMsg.setSubject(mailSubject);
			return true;
		} catch (Exception e) {
			LOGGER.error("定义邮件主题发生错误！");
			return false;
		}
	}

	/**
	 * 定义邮件正文
	 * @param mailBody
	 * @return
	 */
	public boolean setBody(String mailBody) {
		try {
			BodyPart bodyPart = new MimeBodyPart();
			bodyPart.setContent(mailBody, "text/html;charset=UTF-8");
			if(multiPart == null) {
				multiPart = new MimeMultipart();
			}
			multiPart.addBodyPart(bodyPart);


			//添加附件
			List<String> afns = getAttachFileNames();
			if(afns != null && afns.size() != 0) {
				for(String attachFile : afns) {
					bodyPart = new MimeBodyPart();
					//得到数据源
					FileDataSource fds = new FileDataSource(attachFile);
					//得到附件本身并放入BodyPart
					bodyPart.setDataHandler(new DataHandler(fds));
					//得到文件名并编码（防止中文文件名乱码）同样放入BodyPart
					bodyPart.setFileName(MimeUtility.encodeText(fds.getName()));
					multiPart.addBodyPart(bodyPart);
				}
			}

			return true;
		} catch (Exception e) {
			LOGGER.error("定义邮件正文时发生错误！" + e);
			return false;
		}
	}

	/**
	 * 定义收信人，多个用,分隔
	 * @param tos
	 * @return
	 */
	public boolean setTo(String tos) {
		if (FrameStringUtil.isEmpty(tos)) {
			return false;
		}
		try {
			List<String> toArr = FrameStringUtil.toArray(tos, ",");
			List<InternetAddress> address = new ArrayList<InternetAddress>();
			for (String to : toArr) {
				if(FrameStringUtil.isNotEmpty(to)) {
					address.add(new InternetAddress(to));
				}
			}
			mimeMsg.setRecipients(Message.RecipientType.TO, address.toArray(new InternetAddress[address.size()]));
			//mimeMsg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
			return true;
		} catch (Exception e) {
			LOGGER.error("设置收件人异常: " + e.getMessage());
			return false;
		}
	}

	/**
	 * 定义抄送人
	 * @param copyto
	 * @return
	 */
	public boolean setCopyTo(String copyto) {
		if (copyto == null) {
			return false;
		}
		try {
			mimeMsg.setRecipients(Message.RecipientType.CC, (Address[]) InternetAddress.parse(copyto));
			return true;
		} catch (Exception e) {
			LOGGER.error("设置抄送人异常: " + e.getMessage());
			return false;
		}
	}

	//发送邮件模块
	private boolean sendOut() {
		if(isSend != null && !isSend.booleanValue()) {
			return false;
		}
		try {
			mimeMsg.setContent(multiPart);
			mimeMsg.saveChanges();
			LOGGER.info("邮件发送中....");
			Session mailSession = Session.getInstance(props, null);
			Transport transport = mailSession.getTransport("smtp");
			transport.connect((String) props.get("mail.smtp.host"), username, password);
			transport.sendMessage(mimeMsg, mimeMsg.getRecipients(Message.RecipientType.TO));
			LOGGER.info("发送成功！");
			transport.close();
			return true;
		} catch (Exception e) {
			LOGGER.error("发送失败！" + e.getMessage(), e);
			return false;
		}
	}
	
	/**
	 * 调用sendOut方法完成发送
	 * @param tos		接收人 多个用,分隔
	 * @param title		标题
	 * @param content	正文
	 * @return
	 */
	public boolean send(String tos, String title, String content) {
		if(isSend != null && !isSend.booleanValue()) {
			return false;
		}
		if (!setSubject(title)) {
			return false;
		}
		if (!setBody(content)) {
			return false;
		}
		if (!setTo(tos)) {
			return false;
		}
		if (!sendOut()) {
			return false;
		}
		return true;
	}

	/**
	 * 调用sendOut方法完成发送[支持抄送]
	 * @param tos		接收人 多个用,分隔
	 * @param copyto	抄送人
	 * @param title		标题
	 * @param content	正文
	 * @return
	 */
	public boolean send(String tos, String copyto, String title, String content) {
		if(isSend != null && !isSend.booleanValue()) {
			return false;
		}
		if (!setSubject(title)) {
			return false;
		}
		if (!setBody(content)) {
			return false;
		}
		if (!setTo(tos)) {
			return false;
		}
		if (!setCopyTo(copyto)) {
			return false;
		}
		if (!sendOut()) {
			return false;
		}
		return true;
	}

	public List<String> getAttachFileNames() {
		return attachFileNames;
	}
	
	public void setAttachFileNames(List<String> attachFileNames) {
		this.attachFileNames = attachFileNames;
	}
	/*public static void main(String[] args) {
		// smtp服务器
		String smtp = "smtp.163.com";
		// 邮件显示名称
		String from = "cactus_jing@163.com";
		// 发件人真实的账户名
		String username = "cactus_jing@163.com";
		// 发件人密码
		String password = "123456";
		FrameMailUtil theMail = new FrameMailUtil(smtp, from, username, password);
		String to = "335230096@qq.com";// 收件人的邮件地址，必须是真实地址
		String copyto = "";// 抄送人邮件地址
		String subject = "测试邮件";// 邮件标题
		String content = "你好！";// 邮件内容
		List<String> afns = new ArrayList<String>();
		afns.add("C:\\Users\\yuejing\\Desktop\\复制sql.txt");
		//设置附件
		theMail.setAttachFileNames(afns);
		boolean bool = theMail.send(to, copyto, subject, content);
		System.out.println(bool);
		LOGGER.info("发送结果: " + bool);
	}*/
}